 /*
 * @file       bsp_pthread.cpp
 * @author     MatCoreShu (2874567545@qq.com)
 * @date       2025-05-21
 * @version    1.0
 * @copyright  Copyright (c) 2025  [ zhangshuoshi ]
 * @API说明     (API Documentation)
 * ==============================================
    void Pthread_Send_Command(ThreadDevContext* ctx, ThreadControlCmd cmd);
    void Pthread_WaitCmdProcess(ThreadDevContext* ctx);
    bool Pthread_IsAlive(ThreadDevContext* ctx);
    void Pthread_FreeWorkResource(ThreadDevContext* ctx);
 * ==============================================
 */
#include "bsp_pthread.h"

// 安全退出线程的函数（新增）
void signal_thread_to_exit(pthread_t *thread_id, volatile int *exit_flag) 
{
   if (thread_id == 0)
   {
      return;
   }
   
    // 设置退出标志
    *exit_flag = 1;
    
    // 等待线程自行退出
    time_t start_time = time(NULL);
    while(time(NULL) - start_time < 5) {
        if(pthread_tryjoin_np(*thread_id, NULL) == 0) {
            printf("线程已正常结束\n");
            return;
        }
        usleep(100000);
    }
    
    // 超时处理（仍建议避免，但提供最后手段）
    printf("线程退出超时，尝试强制终止（谨慎使用）\n");
    if(pthread_cancel(*thread_id) != 0) {
        perror("pthread_cancel error");
    }
    if(pthread_join(*thread_id, NULL) != 0) {
        perror("pthread_join error");
    }
}
/**
 * @brief MCU Data Reading Thread Callback
 * @description This thread is responsible for asynchronously reading data from the MCU via UART. 
 *              It retrieves UART configuration parameters through the context structure and ensures 
 *              thread-safe state updates using mutex locks.
 * @param arg Thread context parameter, pointing to a ThreadDevContext structure
 * @return NULL (standard return value for thread functions)
 * @notes 
 * 1. **Thread Lifecycle Management**:
 *    - Locks the context state using a mutex when starting
 *    - Updates the thread state to CMD_STATE_RUNNING (in-progress)
 *    - Releases the lock after completing UART initialization
 * 2. **Resource Management**:
 *    - Dynamically allocates and initializes a Uart_t structure
 *    - Fetches UART configuration (baud rate, data bits, etc.) from the context
 *    - Prints UART parameters for debugging verification
 * 3. **Safety Mechanisms**:
 *    - Performs null pointer check on the context pointer
 *    - Uses pthread_mutex_lock/unlock to protect shared states
 */

void *thd_read_mcu(void *arg)
{
   printf("------thd_uart_send_mcu-----\n");

//new:更新参数    
   unsigned char rx_buf[64] = {0};
   while (1)
   {
      /* code */
      pthread_mutex_lock(&mcu_data_lock);
      int read_byte = read(g_uart_mcu->fd, rx_buf, sizeof(rx_buf));
      pthread_mutex_unlock(&mcu_data_lock);

      if (read_byte > 0){
         /* mcu数据解析 */
         //最后需要使用fd集合来传递 控制subdev所使用的fd   ctx->args->uart->fd-->Bsp_Global_fd *fd_collect
         UartGetMcuData(g_uart_mcu->fd,rx_buf,read_byte);
      }

      if (read_byte <= 0){
         continue;
      }
      usleep(500);
   }
      
}

/* 负责监控所有的串口设备返回的数据，然后打包发给mcu连接的串口 */
#define DEBUG 1  // 启用调试打印
void *thd_send_mcu(void *arg)
{
   printf("------thd_uart_send_mcu-----\n");
   int ret = -1;

   int bytes_read = 0;
   uint8_t readbuf[265];
   /*select监控是否可读*/
   fd_set readfds;
   struct timeval timeout;
   int max_fd;

   //定义一个待更新和发送的十六进制数据缓存数组update_buf
   uint8_t checksum = 0;
   uint8_t MaxNum = 32;

   /* 可见光相关参数的初始化部分 */
   while (1)
   {
   /* debug更新全局指针fd */
   // printf("Mcu FD: %d\n",  g_uart_mcu->fd); 
   // printf("Laser FD: %d\n", g_uart_laser->fd); 
   // printf("ICR FD: %d\n",    g_uart_icr->fd); 
   // printf("Visble FD: %d\n",  g_uart_vis->fd); 
   // printf("Usb0 FD: %d\n",  g_uart_usb0->fd); 


      uint8_t update_buf[MaxNum] = {0};
      //固定帧头
      update_buf[0] = 0xEE;
      update_buf[1] = 0x16;       // 同步码
      /*select fd*/ 
      FD_ZERO(&readfds);
      /* add fds */
      FD_SET(g_uart_laser->fd,  &readfds);
      FD_SET(g_uart_icr->fd ,    &readfds);
      FD_SET(g_uart_vis->fd, &readfds);
      int fds[] = {g_uart_laser->fd, g_uart_icr->fd, g_uart_vis->fd};
      /* caclu MAX */
      max_fd = fds[0];
      for (int i = 1; i < sizeof(fds) / sizeof(fds[0]); i++) 
      {
         if (fds[i] > max_fd) {
            max_fd = fds[i];
         }
      }
      /* select_poll */
      // printf("Max FD: %d\n", max_fd);
      timeout.tv_sec = 0;  
      timeout.tv_usec = 500000; 

      /*select wait data <--- laser_ctx->args->uart->fd */ 
      ret = select(max_fd + 1, &readfds, NULL, NULL, &timeout);

      if (ret < 0) {
         perror("Error laser_polling_thd in select()");
         continue;
      } else if (ret == 0) {
         /* 每50ms监听一次，在cpu的1/2.5GHz时间 */
         continue;
      }

      /* get data from subuart */
/* LASER SUBDEV*/
      if (FD_ISSET(g_uart_laser->fd, &readfds)) 
      {
         memset(readbuf, 0, sizeof(readbuf));
         bytes_read = read(g_uart_laser->fd, readbuf, sizeof(readbuf));
         
         if (bytes_read > 0) 
         {
             /*01 origin data*/
         #if 0
            printf("Laser Response (%d bytes): [", bytes_read);
            for (int i = 0; i < bytes_read; i++) {
                  printf("%02X ", readbuf[i]);
            }
            printf("]\n");
            if (bytes_read < 15) {
                  printf("Invalid laser response length\n");
                  continue;
            }
         #endif
            /* 02.1:analyze agreement part 1 */ 
            if (readbuf[0] == 0xCC && readbuf[14] == 0x55) {
                  int8_t env_temp         = readbuf[2];     // 环境温度
                  uint8_t self_check_info = readbuf[3];     // 自检信息 03:正常出光 FF：不出光
                  uint8_t work_mode       = readbuf[4];     // 工作模式 01：高强度工作 00：正常
                  uint8_t checksum        = readbuf[13];    // 校验字       
               #if 0
                  printf("环境温度: %d °C\n", env_temp);
                  
                  if (self_check_info == 0x03) {
                     printf("自检信息: 正常出光\n");
                  } 
                  else if (self_check_info == 0xFF) {
                     printf("自检信息: 不出光\n");
                  } else {
                     printf("自检信息: 未知状态\n");
                  }
                  if (work_mode == 0x01) {
                     printf("工作模式: 高强度工作\n");
                  } else if (work_mode == 0x00) {
                     printf("工作模式: 正常工作\n");
                  } else {
                     printf("工作模式: 未知模式\n");
                  }
                  
                  printf("校验字: 0x%02X\n", checksum);
               #endif
            }
            
            /* 02.1:analyze agreement part 2 */ 
            if (readbuf[0] == 0xAA && readbuf[14] == 0x55) {
                  uint8_t  target_count         = readbuf[1];     // 目标个数
                  uint32_t laser_first_distance = (readbuf[2] << 16) | (readbuf[3] << 8) | readbuf[4];
                  uint32_t laser_end_distance   = (readbuf[5] << 16) | (readbuf[6] << 8) | readbuf[7];
                  uint8_t  measure_status       = readbuf[8];   // 测量状态
                  uint32_t light_emission_count = (readbuf[9] << 24) | (readbuf[10] << 16) | (readbuf[11] << 8) | readbuf[12];  // 出光次数

               /* 更新数据到update_buf中，使用ctx->lock保护 */
               pthread_mutex_lock(&mcu_data_lock);
               update_buf[2] = readbuf[1];
               update_buf[3] = readbuf[2];
               update_buf[4] = readbuf[3];
               update_buf[5] = readbuf[4];
               update_buf[6] = readbuf[5];
               update_buf[7] = readbuf[6];
               update_buf[8] = readbuf[7];
               update_buf[9] = readbuf[8];
               update_buf[10] = readbuf[9];
               update_buf[11] = readbuf[10];
               update_buf[12] = readbuf[11];
               update_buf[13] = readbuf[12];
               pthread_mutex_unlock(&mcu_data_lock);
               memset(readbuf, 0, sizeof(readbuf));
            }
         } else if (bytes_read < 0) {
               perror("Error reading from laser UART");
         }
      }
/* VIS SUBDEV*/
      if (FD_ISSET(g_uart_vis->fd, &readfds)) 
      {
         memset(readbuf, 0, sizeof(readbuf));
         bytes_read = read(g_uart_vis->fd, readbuf, sizeof(readbuf));
         
         if (bytes_read > 0) {
            /*01 origin data*/
            #if 0
            printf("Vis Response (%d bytes): [", bytes_read);
            for (int i = 0; i < bytes_read; i++) {
                  printf("%02X ", readbuf[i]);
            }
            printf("]\n");
            #endif
         }
         memset(readbuf, 0, sizeof(readbuf));
      }
/* ICR SUBDEV*/
      /*版本1 ok*/
      if (FD_ISSET(g_uart_icr->fd, &readfds)) {
         
         bytes_read = read(g_uart_icr->fd, readbuf, sizeof(readbuf));
         
         static uint8_t frame_buffer[54] = {0};  // 帧缓冲区，固定大小54字节
         memset(frame_buffer, 0, sizeof(frame_buffer));
         static int buffer_pos = 0;             // 缓冲区当前位置
         
         if (bytes_read > 0) {
      #if 0
            printf("icr:%d字节数据已接收\n", bytes_read);
      #endif
            
            for (int i = 0; i < bytes_read; i++) {
                  // 帧头检测
                  if (buffer_pos == 0 && readbuf[i] != 0x55) {
                     continue;  // 不是帧头，跳过
                  }
                  
                  // 存储数据到缓冲区
                  frame_buffer[buffer_pos++] = readbuf[i];
                  
                  // 检查是否收到完整帧
                  if (buffer_pos == 54) {
      #if 0
                     // 打印完整帧数据
                     printf("收到完整帧(54字节):\n");
                     for (int j = 0; j < 54; j++) {
                        printf("%02X ", frame_buffer[j]);
                        
                        // 每16字节换行，并添加ASCII表示
                        if ((j + 1) % 16 == 0) {
                              printf(" | ");
                              for (int k = j - 15; k <= j; k++) {
                                 if (frame_buffer[k] >= 32 && frame_buffer[k] <= 126) {
                                    printf("%c", frame_buffer[k]);
                                 } else {
                                    printf(".");
                                 }
                              }
                              printf("\n");
                        }
                     }
                     
                     // 处理不足16字节的剩余数据
                     if (54 % 16 != 0) {
                        int remainder = 16 - (54 % 16);
                        for (int j = 0; j < remainder; j++) {
                              printf("   ");
                        }
                        printf(" | ");
                        for (int j = 54 - (54 % 16); j < 54; j++) {
                              if (frame_buffer[j] >= 32 && frame_buffer[j] <= 126) {
                                 printf("%c", frame_buffer[j]);
                              } else {
                                 printf(".");
                              }
                        }
                        printf("\n");
                     }
                     
                     // 单独打印第15和16字节的数据（索引14和15）
                     printf("第15和16字节的数据: 0x%02X 0x%02X\n", 
                           frame_buffer[14], frame_buffer[15]);
                     
                     // 打印保存信息
                     printf("已将0x%02X保存到update_buf[18]\n", update_buf[18]);
                     
                     printf("----------------------------------------\n");
      #endif
                     
                     // 将第16字节的数据(索引15)保存到update_buf[18]
                     pthread_mutex_lock(&mcu_data_lock);
                     update_buf[17] = frame_buffer[12];
                     update_buf[18] = frame_buffer[15];
                     pthread_mutex_unlock(&mcu_data_lock);
                     memset(frame_buffer, 0, sizeof(frame_buffer));
                     // 重置缓冲区位置，准备接收下一帧
                     buffer_pos = 0;
                  }
            }
         }
      }


      pthread_mutex_lock(&mcu_data_lock);
      uint8_t checksum = 0;
      for (int i = 0; i < MaxNum - 1; i++) {
         checksum += update_buf[i];
      }
      update_buf[MaxNum - 1] = checksum;

      // 打印即将发送的数据（十六进制）
      #if 0
      printf("即将发送的数据(十六进制，%d字节):\n", MaxNum);
      for (int i = 0; i < MaxNum; i++) {
         printf("%02X ", update_buf[i]);
         if ((i + 1) % 16 == 0) printf("\n");  // 每16字节换行
      }
      printf("\n");
      #endif
      // 发送数据并检查返回值
      ssize_t bytes_sent = write(g_uart_mcu->fd, update_buf, MaxNum);
      #if 0
      if (bytes_sent == MaxNum) {
         printf("发送成功: 发送了 %zd 字节 (预期 %d 字节)\n", bytes_sent, MaxNum);
      } else if (bytes_sent == -1) {
         perror("发送失败,#thd_send_mcu#");
         printf("错误码: %d\n", errno);
      } else {
         printf("部分发送: 发送了 %zd 字节 (预期 %d 字节)\n", bytes_sent, MaxNum);
      }
      #endif
      pthread_mutex_unlock(&mcu_data_lock);


      // sleep(10);
      usleep(500000);
   }

}

/*laser poll thd */
//避免cpu空转占用cpu核心，使用select\poll\epoll进行异步IO操作；
void *laser_polling_thd(void *arg)
{
   printf("------laser_polling_thd-----\n");
   int ret = -1;
   int bytes_read = 0;
   uint8_t buf[64];
   /*select监控是否可读*/
   fd_set readfds;
   struct timeval timeout;
   int max_fd;

   //new:更新参数
   /*承接结构体上文*/
   ThreadDevContext* laser_ctx = (ThreadDevContext*)arg;
   if (!laser_ctx) {
      perror("Invalid thread context");
      return NULL;
   }

   /* 加锁 -> c*/
   pthread_mutex_lock(&laser_ctx->lock);

   //这个状态要由全局变量进行控制
   laser_ctx->thdstate = CMD_STATE_RUNNING;
   uart_show_data(laser_ctx->args->uart);
   /* 解锁 */
   pthread_mutex_unlock(&laser_ctx->lock);
//new:更新参数    
   while (1)
   {   
      /*select fd*/ 
      FD_ZERO(&readfds);
      FD_SET(laser_ctx->args->uart->fd, &readfds);
      timeout.tv_sec = 1;  // 1秒
      timeout.tv_usec = 0; // 0微秒

      /*select wait data <--- laser_ctx->args->uart->fd */ 
      ret = select(laser_ctx->args->uart->fd + 1, &readfds, NULL, NULL, &timeout);

      if (ret < 0) {
         perror("Error laser_polling_thd in select()");
         usleep(100000);  // 100ms
         continue;
      } else if (ret == 0) {
         /* 每秒等一次，在cpu的1/2.5GHz时间 */
         continue;
      }

      /*select监控数据后，有数据返回 bool（true:1,false:0）*/ 
      if (FD_ISSET(laser_ctx->args->uart->fd, &readfds)) 
      {
         memset(buf, 0, sizeof(buf));
         bytes_read = read(laser_ctx->args->uart->fd, buf, sizeof(buf));
         
         if (bytes_read > 0) {
            parse_laser_response(buf, bytes_read);
         } else if (bytes_read < 0) {
            perror("Error reading from laser UART");
            usleep(100000);  // 100ms
         }
     }
   }
}

/*监听所有串口返回soc的数据 thd */
//避免cpu空转占用cpu核心，使用select\poll\epoll进行异步IO操作；
void *Uarts_SelectFDs_thd(void *arg)
{
   printf("------Uarts_SelectFDs_thd-----\n");
   int ret = -1;
   int bytes_read = 0;
   uint8_t buf[265];



   /*select监控是否可读*/
   fd_set readfds;
   struct timeval timeout;
   int max_fd;

//new:更新参数
//new:更新参数    

   /* 更新全局指针fd */
   printf("Laser FD: %d\n",   *laser_fd); // 使用 *laser_fd 获取实际值
   printf("ICR FD: %d\n",     *icr_fd); // 使用 *icr_fd 获取实际值
   printf("Visble FD: %d\n",  *vis_fd); // 使用 *vis_fd 获取实际值
   while (1)
   {   
      /*select fd*/ 
      FD_ZERO(&readfds);
      /* add fds */
      FD_SET(*laser_fd,  &readfds);
      FD_SET(*icr_fd,    &readfds);
      FD_SET(*vis_fd, &readfds);
      int fds[] = {*laser_fd, *icr_fd, *vis_fd};
      /* caclu MAX */
      max_fd = fds[0];
      for (int i = 1; i < sizeof(fds) / sizeof(fds[0]); i++) 
      {
         if (fds[i] > max_fd) {
            max_fd = fds[i];
         }
      }
      /* 开始轮询 */
      printf("Max FD: %d\n", max_fd);
      timeout.tv_sec = 0;  
      timeout.tv_usec = 500000; 

      /*select wait data <--- laser_ctx->args->uart->fd */ 
      ret = select(max_fd + 1, &readfds, NULL, NULL, &timeout);

      if (ret < 0) {
         perror("Error laser_polling_thd in select()");
         continue;
      } else if (ret == 0) {
         /* 每50ms监听一次，在cpu的1/2.5GHz时间 */
         continue;
      }

      /*select监控数据后，有数据返回 bool（true:1,false:0）*/ 
      /* 1 激光模块串口数据回调监控*/
      if (FD_ISSET(*laser_fd, &readfds)) 
      {
         memset(buf, 0, sizeof(buf));
         bytes_read = read(*laser_fd, buf, sizeof(buf));
         
         if (bytes_read > 0) {
            parse_laser_response(buf, bytes_read);
         } else if (bytes_read < 0) {
            perror("Error reading from laser UART");
         }
      }
      /* 2 红外模块串口数据回调监控*/
      if (FD_ISSET(*icr_fd, &readfds)) 
      {
         memset(buf, 0, sizeof(buf));
         bytes_read = read(*icr_fd, buf, sizeof(buf));
         
         if (bytes_read > 0) {

            //recv hex data
            printf("Icr Response (%d bytes): [", bytes_read);
            for (int i = 0; i < bytes_read; i++) {
               printf("%02X ", buf[i]);
            }
            printf("]\n");

         } else if (bytes_read < 0) {
            perror("Error reading from laser UART");
         }
      }
      /* 3 可见模块串口数据回调监控*/
      if (FD_ISSET(*vis_fd, &readfds)) 
      {
         memset(buf, 0, sizeof(buf));
         bytes_read = read(*vis_fd, buf, sizeof(buf));
         
         if (bytes_read > 0) {

            //recv hex data
            printf("Vis Response (%d bytes): [", bytes_read);
            for (int i = 0; i < bytes_read; i++) {
               printf("%02X ", buf[i]);
            }
            printf("]\n");

         } else if (bytes_read < 0) {
            perror("Error reading from laser UART");
         }
     }

   }

}

void *thd_timeout_5min(void *arg)
{
   printf("------thd_timeout_5min-----\n");

   while (1)
   {
      /* code */
      usleep(480000); // 5分钟
      printf("Free work resource every 5 minutes\n");
   }

}
